import type { Ref } from 'vue'

export interface CacheConfig<T> {
  // 数据获取函数
  fetcher: () => Promise<T>
  // 数据存储的 ref
  dataRef: Ref<T>
  // 加载状态的 ref
  loadingRef: Ref<boolean>
  // 数据转换函数，可选
  transform?: (data: any) => T
  // 自定义数据验证函数，用于判断数据是否有效
  validator?: (data: T) => boolean
}

export class CacheManager<T> {
  private currentPromise: Promise<void> | null = null
  private config: Required<CacheConfig<T>>

  constructor(config: CacheConfig<T>) {
    this.config = {
      transform: (data: any) => data as T,
      validator: this.defaultValidator.bind(this),
      ...config,
    }
  }

  // 默认的数据验证函数
  private defaultValidator(data: T): boolean {
    if (data === null || data === undefined) {
      return false
    }

    // 如果是数组，检查长度
    if (Array.isArray(data)) {
      return data.length > 0
    }

    // 如果是对象，检查是否为空对象
    if (typeof data === 'object') {
      return Object.keys(data).length > 0
    }
    // 其他类型，只要不是 null/undefined 就认为有数据
    return true
  }

  // 检查是否有有效数据
  private hasValidData(): boolean {
    return this.config.validator(this.config.dataRef.value)
  }

  // 获取数据的主方法
  async getData(options: { forceRefresh?: boolean } = {}) {
    const { forceRefresh = false } = options

    // 如果有数据且不强制刷新，直接返回
    if (this.hasValidData() && !forceRefresh) {
      return this.config.dataRef.value
    }

    // 复用进行中的请求
    if (this.currentPromise) {
      await this.currentPromise
      return this.config.dataRef.value
    }

    this.config.loadingRef.value = true
    this.currentPromise = this.config
      .fetcher()
      .then(rawData => {
        const transformedData = this.config.transform(rawData)
        this.config.dataRef.value = transformedData
      })
      .catch(error => {
        console.error('Failed to fetch data:', error)
        throw error
      })
      .finally(() => {
        this.config.loadingRef.value = false
        this.currentPromise = null
      })

    await this.currentPromise
    return this.config.dataRef.value
  }

  // 重置
  reset() {
    this.currentPromise = null
    this.config.loadingRef.value = false
  }

  // 清空数据
  clear() {
    this.config.dataRef.value = null as T
    this.reset()
  }

  // 手动设置数据
  setData(data: T) {
    this.config.dataRef.value = data
  }

  // 获取当前数据（不触发请求）
  getCurrentData(): T {
    return this.config.dataRef.value
  }

  // 检查是否正在加载
  isLoading(): boolean {
    return this.config.loadingRef.value
  }
}

// 便捷的创建函数
export function createCacheManager<T>(config: CacheConfig<T>) {
  return new CacheManager<T>(config)
}

// 为数组类型提供特殊的创建函数
export function createArrayCacheManager<T>(config: Omit<CacheConfig<T[]>, 'validator'>) {
  return new CacheManager<T[]>({
    ...config,
    validator: (data: T[]) => Array.isArray(data) && data.length > 0,
  })
}

// 为对象类型提供特殊的创建函数
export function createObjectCacheManager<T extends Record<string, any>>(
  config: Omit<CacheConfig<T>, 'validator'>,
) {
  return new CacheManager<T>({
    ...config,
    validator: (data: T) =>
      data !== null &&
      data !== undefined &&
      typeof data === 'object' &&
      Object.keys(data).length > 0,
  })
}
